package com.sunwayworld.basemodule.rm.equipment.io;

import com.sunwayworld.baseline.framework.override.LimsExcelHelper;
import com.sunwayworld.basemodule.rm.equipment.bean.LimsEquipmentBean;
import com.sunwayworld.basemodule.rm.equipment.bean.LimsEquipmentMeasureBean;
import com.sunwayworld.basemodule.rm.equipment.service.LimsEquipmentMeasureService;
import com.sunwayworld.basemodule.rm.equipment.service.LimsEquipmentService;
import com.sunwayworld.framework.context.ApplicationContextHelper;
import com.sunwayworld.framework.exception.InvalidDataException;
import com.sunwayworld.framework.i18n.I18nHelper;
import com.sunwayworld.framework.io.file.FilePathDTO;
import com.sunwayworld.framework.io.file.FilePathManager;
import com.sunwayworld.framework.mybatis.mapper.MatchPattern;
import com.sunwayworld.framework.mybatis.mapper.SearchFilter;
import com.sunwayworld.framework.spring.annotation.GikamBean;
import com.sunwayworld.framework.utils.BeanUtils;
import com.sunwayworld.framework.utils.NumberUtils;
import com.sunwayworld.framework.utils.StringUtils;
import com.sunwayworld.module.item.file.bean.CoreFileBean;
import com.sunwayworld.module.item.file.bean.CoreFileImportResultDTO;
import com.sunwayworld.module.item.file.function.CoreFileImportFunction;
import com.sunwayworld.module.item.file.utils.CoreFileUtils;
import com.sunwayworld.module.sys.code.bean.CoreCodeBean;
import com.sunwayworld.module.sys.code.service.CoreCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


/**
 * @author xiongym  2020-3-18
 */
@Component(value = "LimsEquipmentImportFileFunction")
@GikamBean
public class LimsEquipmentImportFileFunction implements CoreFileImportFunction {

    @Autowired
    @Lazy
    private LimsEquipmentService equipmentService;

    @Autowired
    @Lazy
    private LimsEquipmentMeasureService equipmentMeasureService;

    @Autowired
    @Lazy
    CoreCodeService coreCodeService;

    @Override
    @Transactional
    public CoreFileImportResultDTO apply(CoreFileBean coreFileBean) {
        CoreFileImportResultDTO importResultRepresentation = new CoreFileImportResultDTO();

        FilePathDTO fr = CoreFileUtils.toFilePath(coreFileBean);
        List<LimsEquipmentBean> equipmentList = LimsExcelHelper.readDataFromExcel(FilePathManager.getLocalPath(fr).toString(), 1, 2, LimsEquipmentBean.class);
        if (equipmentList.isEmpty()) {
            // 存在错误信息
            throw new InvalidDataException(I18nHelper.getMessage("MODULE.COMMON.IMPORT_FILE.DATA_IS_NULL"));
        }
        // 仪器状态
        List<CoreCodeBean> equipStates = coreCodeService.selectListByFilter(SearchFilter.instance().match("codeCategoryId", "equipState").filter(MatchPattern.EQ));
        List<CoreCodeBean> eqClass = coreCodeService.selectListByFilter(SearchFilter.instance().match("codeCategoryId", "eqClass").filter(MatchPattern.EQ));
        List<CoreCodeBean> useOrgs = coreCodeService.selectListByFilter(SearchFilter.instance().match("codeCategoryId", "equip-useOrg").filter(MatchPattern.EQ));
        List<CoreCodeBean> locations = coreCodeService.selectListByFilter(SearchFilter.instance().match("codeCategoryId", "equip-location").filter(MatchPattern.EQ));
        List<String> columns = Arrays.asList("equipCode", "equipName");
        List<String> colNames = Arrays.asList("【设备编号】", "【设备名称】");
        equipmentList.forEach(a -> {
            StringBuilder msg = new StringBuilder();
            for (int i = 0; i < columns.size(); i++) {
                Object value = BeanUtils.getPropertyValue(a, columns.get(i));
                if (value == null || (value.getClass().equals(String.class) && value.equals(""))) {
                    msg.append(colNames.get(i));
                }
            }
            if (msg.length() > 0) {
                msg.append(" 为必填项；");
            }
            if (msg.length() > 0) {
                if (!StringUtils.isBlank(a.getExt$Item("validateimpmsg"))) {
                    a.setExt$Item("validateimpmsg", a.getExt$Item("validateimpmsg").concat(msg.toString()));
                } else {
                    a.setExt$Item("validateimpmsg", msg.toString());
                }
            }
            if (!StringUtils.isBlank(a.getEquipClass())) {
                Optional<CoreCodeBean> ec = eqClass.stream().filter(es -> es.getCodeName().equals(a.getEquipClass())).findAny();
                if (ec.isPresent()) {
                    a.setEquipClass(ec.get().getCode());
                } else {
                    if (!StringUtils.isBlank(a.getExt$Item("validateimpmsg"))) {
                        a.setExt$Item("validateimpmsg", a.getExt$Item("validateimpmsg").concat("【仪器类别】导入信息非选项中内容；"));
                    } else {
                        a.setExt$Item("validateimpmsg", "【仪器类别】导入信息非选项中内容；");
                    }
                }
            }
            if (!StringUtils.isBlank(a.getMeasureFlag())) {
                if (!StringUtils.equals("是", a.getMeasureFlag()) && !StringUtils.equals("否", a.getMeasureFlag())) {
                    if (!StringUtils.isBlank(a.getExt$Item("validateimpmsg"))) {
                        a.setExt$Item("validateimpmsg", a.getExt$Item("validateimpmsg").concat("【是否需要计量】导入信息非选项中内容；"));
                    } else {
                        a.setExt$Item("validateimpmsg", "【是否需要计量】导入信息非选项中内容；");
                    }
                } else {
                    if ("是".equals(a.getMeasureFlag())) {
                        a.setMeasureFlag("1");
                    } else {
                        a.setMeasureFlag("0");
                    }
                }
            }
            if (!StringUtils.isBlank(a.getEquipState())) {
                Optional<CoreCodeBean> ec = equipStates.stream().filter(es -> es.getCodeName().equals(a.getEquipState())).findAny();
                if (ec.isPresent()) {
                    a.setEquipState(ec.get().getCode());
                } else {
                    if (!StringUtils.isBlank(a.getExt$Item("validateimpmsg"))) {
                        a.setExt$Item("validateimpmsg", a.getExt$Item("validateimpmsg").concat("【仪器状态】导入信息非选项中内容；"));
                    } else {
                        a.setExt$Item("validateimpmsg", "【仪器状态】导入信息非选项中内容；");
                    }
                }
            }
            if (!StringUtils.isBlank(a.getUseDept())) {
                String[] orgNames = a.getUseDept().split(",");
                if (Arrays.stream(orgNames).filter(s -> !StringUtils.isBlank(s)).anyMatch(on -> useOrgs.stream().noneMatch(uo -> uo.getCodeName().equals(on)))) {
                    if (!StringUtils.isBlank(a.getExt$Item("validateimpmsg"))) {
                        a.setExt$Item("validateimpmsg", a.getExt$Item("validateimpmsg").concat("【使用部门】导入信息非选项中内容；"));
                    } else {
                        a.setExt$Item("validateimpmsg", "【使用部门】导入信息非选项中内容；");
                    }
                } else {
                    List<String> sb = new ArrayList<>();
                    Arrays.stream(orgNames).filter(s -> !StringUtils.isBlank(s)).forEach(s -> {
                        useOrgs.stream().filter(uo -> uo.getCodeName().equals(s)).findAny().ifPresent(uo -> {
                            sb.add(uo.getCode());
                        });
                    });
                    a.setUseDept(String.join(",", sb));
                }
            }
            if (!StringUtils.isBlank(a.getLocation())) {
                Optional<CoreCodeBean> ec = locations.stream().filter(es -> es.getCodeName().equals(a.getLocation())).findAny();
                if (ec.isPresent()) {
                    a.setLocation(ec.get().getCode());
                } else {
                    if (!StringUtils.isBlank(a.getExt$Item("validateimpmsg"))) {
                        a.setExt$Item("validateimpmsg", a.getExt$Item("validateimpmsg").concat("【存放位置】导入信息非选项中内容；"));
                    } else {
                        a.setExt$Item("validateimpmsg", "【存放位置】导入信息非选项中内容；");
                    }
                }
            }
        });
        Map<String, List<LimsEquipmentBean>> groupByEquipCode = equipmentList.stream().filter(e -> !StringUtils.isBlank(e.getEquipCode())).collect(Collectors.groupingBy(LimsEquipmentBean::getEquipCode));
        groupByEquipCode.forEach((c, temp) -> {
            if (temp.size() > 1) {
                temp.forEach(a -> {
                    if (!StringUtils.isBlank(a.getExt$Item("validateimpmsg"))) {
                        a.setExt$Item("validateimpmsg", a.getExt$Item("validateimpmsg").concat("表格中字段【设备编号】存在重复；"));
                    } else {
                        a.setExt$Item("validateimpmsg", "表格中字段【设备编号】存在重复；");
                    }
                });
            }
        });

        // 查有没有重复设备编号的
        List<LimsEquipmentBean> exists = equipmentService.selectListByFilter(SearchFilter.instance().match("EQUIPCODE", new ArrayList<>(groupByEquipCode.keySet())).filter(MatchPattern.OR));
        if (exists != null && exists.size() > 0) {
            exists.forEach(e -> {
                List<LimsEquipmentBean> temp = groupByEquipCode.get(e.getEquipCode());
                if (temp != null && !temp.isEmpty()) {
                    temp.forEach(a -> {
                        if (!StringUtils.isBlank(a.getExt$Item("validateimpmsg"))) {
                            a.setExt$Item("validateimpmsg", a.getExt$Item("validateimpmsg").concat("【设备编号】重复导入；"));
                        } else {
                            a.setExt$Item("validateimpmsg", "【设备编号】重复导入；");
                        }
                    });
                }
            });
        }

        // 返还校验结果
        if (equipmentList.stream().anyMatch(i -> !StringUtils.isEmpty(i.getExt$Item("validateimpmsg")))) {
            FilePathDTO filePathDTO = LimsExcelHelper.writeImportFailureListAsExcel(FilePathManager.getLocalPath(fr).toString(), equipmentList, 1, 2, "导入错误信息.xlsx", false);
            importResultRepresentation.setUrl(FilePathManager.getUrl(filePathDTO));
            importResultRepresentation.setMessage("导入失败");
            return importResultRepresentation;
        }

        List<LimsEquipmentMeasureBean> equipmentMeasureBeans = new ArrayList<>();
        List<String> idList = ApplicationContextHelper.getNextSequenceList(equipmentService.getDao().getTable(), equipmentList.size());

        for (int i = 0; i < idList.size(); i++) {
            LimsEquipmentBean lsiLimsEquipmentBean = equipmentList.get(i);
            lsiLimsEquipmentBean.setId(NumberUtils.parseLong(idList.get(i)));
            LimsEquipmentMeasureBean equipmentMeasureBean = new LimsEquipmentMeasureBean();
            equipmentMeasureBean.setId(ApplicationContextHelper.getNextIdentity());
            equipmentMeasureBean.setEquipmentId(lsiLimsEquipmentBean.getId());
            equipmentMeasureBeans.add(equipmentMeasureBean);

        }
        equipmentService.getDao().insert(equipmentList);
        equipmentMeasureService.getDao().insert(equipmentMeasureBeans);
        return importResultRepresentation;

    }

    @Override
    public boolean test(CoreFileBean coreFile, String service) {
        return true;
    }
}
